package com.yincheng.oes.business.schedule;

import com.yincheng.oes.business.dao.DailyClockDao;
import com.yincheng.oes.business.model.dto.TPStudentDailyTaskDTO;
import com.yincheng.oes.business.service.StudentDailyTaskQueryApi;
import com.yincheng.oes.business.service.impl.DailyClockServiceImpl;
import com.yincheng.oes.business.util.SpringContextUtils;
import com.yincheng.oes.sso.entity.User;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author yangsiyong
 * @version 1.0
 * @description: 查询APP数据并更新学员每日任务信息
 * @date 2022/3/13 4:51 PM
 */
@Component
public class RefreshDailyTaskInfoScheduleTask extends AbstractScheduleTask implements InitializingBean {
    /**
     * 日志
     */
    private static final Logger LOGGER = LogManager.getLogger(RefreshDailyTaskInfoScheduleTask.class);
    /**
     * 查询学员每日任务信息周期 默认2小时
     */
    private static final Long PERIOD = 24 * 60 * 60 * 1000L;

    private static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat("yyyyMMdd");

    @Override
    protected Date getStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 2);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date time = calendar.getTime();
        if (time.before(new Date())) {
            // 若果当前时间已经是凌晨2点后，需要往后加1天，否则任务会立即执行。
            time = addDay(time, 1);
        }
        return time;
    }

    private Date addDay(Date date, int days) {
        Calendar startDT = Calendar.getInstance();
        startDT.setTime(date);
        startDT.add(Calendar.DAY_OF_MONTH, days);
        return startDT.getTime();
    }

    @Override
    protected long getPeriod() {
        return PERIOD;
    }

    @Override
    public void run() {
        LOGGER.info("start refresh daily task");
        queryAndSaveDailyTaskInfoList();
    }

    private void queryAndSaveDailyTaskInfoList() {
        DailyClockDao dailyClockDao = SpringContextUtils.getBean(DailyClockDao.class);
        DailyClockServiceImpl dailyClockService = SpringContextUtils.getBean(DailyClockServiceImpl.class);

        List<User> users = dailyClockDao.selectDailyClockUsers();

        if (CollectionUtils.isEmpty(users)) {
            return;
        }
        StudentDailyTaskQueryApi studentDailyTaskQueryService
                = SpringContextUtils.getBean(StudentDailyTaskQueryApi.class);
        int count = 0;
        for (User user : users) {
            List<TPStudentDailyTaskDTO> tpStudentDailyTaskDTOS = studentDailyTaskQueryService.batchQueryStudentDailyTasks(user.getUserAccount());
            if (CollectionUtils.isEmpty(tpStudentDailyTaskDTOS)) {
                continue;
            }
            List<TPStudentDailyTaskDTO> afterFilterDailyTaskList = tpStudentDailyTaskDTOS.stream().filter(Objects::nonNull).filter(this::filterExpire).collect(Collectors.toList());
            afterFilterDailyTaskList.forEach(task -> task.setUserId(user.getUserId()));
            //
            for (TPStudentDailyTaskDTO dailyTaskDTO : afterFilterDailyTaskList) {
                int updateCount = dailyClockService.updateDailyTask(dailyTaskDTO);
                count = count + updateCount;
                try {
                    // todo 暂停，防止数据库压力过大 需要优化
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    LOGGER.error("when update dailyTask has error", e);
                }
            }
        }
        LOGGER.info("batch update dailyTask size is {}", count);
    }

    private boolean filterExpire(TPStudentDailyTaskDTO dailyTask) {
        if (Objects.isNull(dailyTask)) {
            return false;
        }
        Date currentDate = new Date();
        String format = YYYY_MM_DD.format(currentDate);
        Integer currentDateIntValue = Integer.valueOf(format);
        if (dailyTask.getTaskDateIntValue() > currentDateIntValue) {
            return false;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        // 暂时只更新最近7天内的数据，
        // todo 这个可以设置成动态的
        calendar.add(Calendar.DATE, -7);
        String last30Date = YYYY_MM_DD.format(calendar.getTime());
        Integer last30DateValue = Integer.valueOf(last30Date);
        if (dailyTask.getTaskDateIntValue() < last30DateValue) {
            return false;
        }
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        ScheduleTaskManager scheduleTaskManager = ScheduleTaskManager.getInstance();
        boolean flag = scheduleTaskManager.offer(new RefreshDailyTaskInfoScheduleTask());
        if (!flag) {
            LOGGER.error("when offer RefreshDailyTaskInfoScheduleTask error");
        }
    }
}
